package com.xj.mq.mqserver.core;

import java.io.Serializable;
import java.util.Arrays;
import java.util.UUID;

/**
 * Created with IntelliJ IDEA
 * Description  消息
 *              能够在网络中传输 也能写入文件
 *              故针对 Message 进行了序列化和反序列化
 * User: 王杰
 * Date: 2025-05-14
 * Time: 10:53
 */
public class Message implements Serializable {
    // 验证版本
    private static final long serialVersionUID = 1L;

    // Massage 最核心的部分
    private BasicProperties basicProperties = new BasicProperties();
    private byte[] body;

    // 以下是: 辅助属性
    // 如果要存储到文件中（持久化）
    // 一个文件会存储很多的消息, 如何找到某个消息, 在文件中的具体位置?
    // 使用下列的 两个偏移量 来进行表示 [offsetBeg, offsetEnd)
    // 这两个属性并不需要序列化保存到文件中
    // 1.此时消息被写入文件后 所在的位置固定 并不需要存储这两个属性
    // 2.属性存在的目的：为了让内存中的Message对象, 能够快速找到对应的硬盘上的Message的位置
    private transient long offsetBeg = 0; // 消息数据的开头距离文件开头的位置偏移（字节）
    private transient long offsetEnd = 0; // 消息数据的结尾距离文件开头的位置便宜（字节）

    // 使用这个属性表示该消息在文件中是否是有效消息（逻辑删除）
    // 0x1 表示有效  0x0 表示无效
    private byte isValid = 0x1;

    // 创建一个工厂方法 封装 创建Message对象的而过程
    // 此方法 创建的Message对象 会 自动生成 唯一的MessageId
    // 如果 routingKey 和 basicProperties 中的 routingKey 冲突了 以外面为主
    public static Message createMessageWithId(String routingKey, BasicProperties basicProperties, byte[] body){
        Message message = new Message();
        if (basicProperties != null) {
            message.setBasicProperties(basicProperties);
        }
        // 此处加上 "M-" 前缀 区分不同实体的ID
        message.setMessageId("M-" + UUID.randomUUID());
        message.basicProperties.setRoutingKey(routingKey);
        message.body = body;
        return message;
    }

    public String getMessageId() {
        return basicProperties.getMessageId();
    }

    public void setMessageId(String messageId) {
        basicProperties.setMessageId(messageId);
    }

    public String getRoutingKey() {
        return basicProperties.getRoutingKey();
    }

    public void setRoutingKey(String routingKey) {
        basicProperties.setRoutingKey(routingKey);
    }

    public int getDeliverMode() {
        return basicProperties.getDeliverMode();
    }

    public void setDeliverMode(int mode) {
        basicProperties.setDeliverMode(mode);
    }

    public BasicProperties getBasicProperties() {
        return basicProperties;
    }

    public void setBasicProperties(BasicProperties basicProperties) {
        this.basicProperties = basicProperties;
    }

    public byte[] getBody() {
        return body;
    }

    public void setBody(byte[] body) {
        this.body = body;
    }

    public long getOffsetBeg() {
        return offsetBeg;
    }

    public void setOffsetBeg(long offsetBeg) {
        this.offsetBeg = offsetBeg;
    }

    public long getOffsetEnd() {
        return offsetEnd;
    }

    public void setOffsetEnd(long offsetEnd) {
        this.offsetEnd = offsetEnd;
    }

    public byte getIsValid() {
        return isValid;
    }

    public void setIsValid(byte isValid) {
        this.isValid = isValid;
    }

    @Override
    public String toString() {
        return "Message{" +
                "basicProperties=" + basicProperties +
                ", body=" + Arrays.toString(body) +
                ", offsetBeg=" + offsetBeg +
                ", offsetEnd=" + offsetEnd +
                ", isValid=" + isValid +
                '}';
    }
}
